package per.hnvcam.searchext.text.impl;

import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;

import per.hnvcam.searchext.text.SentenceExtractor;
import per.hnvcam.searchext.text.SentenceHandler;

/**
 * Created by IntelliJ IDEA.
 * User: violon
 * Date: 4/9/11
 * Time: 4:30 PM
 * To change this template use File | Settings | File Templates.
 */

public class DefaultSentenceExtractorImpl implements SentenceExtractor {

    private StringBuilder sentence;
    private StringBuilder buffer;
    private SentenceHandler handler;

    public DefaultSentenceExtractorImpl() {
        sentence = new StringBuilder();
        buffer = new StringBuilder();
    }

    public void setDocumentLocator(Locator locator) {
    }

    public void startDocument() throws SAXException {
        startSentence();
    }

    public void endDocument() throws SAXException {
    }

    public void startPrefixMapping(String s, String s1) throws SAXException {
    }

    public void endPrefixMapping(String s) throws SAXException {
    }

    public void startElement(String s, String s1, String s2, Attributes attributes) throws SAXException {
        endSentence();
        startSentence();
    }

    public void endElement(String s, String s1, String s2) throws SAXException {
        endSentence();
        startSentence();
    }

    public void characters(char[] chars, int i, int i1) throws SAXException {
        boolean spaced = true;

        buffer.setLength(0);
        for (int idx = i; idx < i1; idx++) {
            if (isWhiteSpace(chars[idx])) {
                if (!spaced) {
                    buffer.append(" ");
                    spaced = true;
                }
            } else {
                if (isEndSentence(chars[idx]) && (idx == i1 - 1 || isWhiteSpace(chars[idx + 1]))) {
                    spaced = true;
                    sentence.append(buffer);
                    endSentence();
                    startSentence();
                    buffer.setLength(0);
                } else {
                    spaced = false;
                    buffer.append(chars[idx]);
                }
            }
        }
        if (buffer.length() > 0) {
            sentence.append(buffer);
        }
    }

    public void ignorableWhitespace(char[] chars, int i, int i1) throws SAXException {
    }

    public void processingInstruction(String s, String s1) throws SAXException {
    }

    public void skippedEntity(String s) throws SAXException {
    }

    private void startSentence() {
        if (sentence.length() > 0) {
            sentence.setLength(0);
        }
    }

    private void endSentence() {
        if (sentence.length() > 0 && handler != null) {
            this.handler.handleSentence(sentence.toString());
        }
    }

    private boolean isWhiteSpace(char c) {
        return c <= 32 || c == '\r' || c == '\n' || c == 0x7f || (0x82 <= c && c <= 0x8d) || (0x90 <= c && c <= 0xa0);
    }

    private boolean isEndSentence(char c) {
        return c == '.' || c == '?' || c == ':' || c == '!';
    }

    public void setHandler(SentenceHandler sentenceHandler) {
        this.handler = sentenceHandler;
    }

}
